package org.example.Thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class NestedThreadExample1 {
    private static final int OUTER_THREAD_COUNT = 12;
    private static final int INNER_THREAD_COUNT = 10;
    private static final int OUTER_TASK_COUNT = 24;
    private static final int OUTER_THREAD_BATCH_COUNT = 2; // 每批外部线程数
    private static final int INNER_THREAD_BATCH_COUNT = 2; // 每批内部线程数
    private static final CountDownLatch OUTER_LATCH = new CountDownLatch(OUTER_THREAD_BATCH_COUNT);


    private static List<Integer> list = new ArrayList<>();

    private static  int zero = 1;

    static class InnerThread implements Runnable {
        private int threadIndex;
        private int outerThreadIndex;
        private int taskIndex;

        public InnerThread(int threadIndex, int outerThreadIndex, int taskIndex)  {
            this.threadIndex = threadIndex;
            this.outerThreadIndex = outerThreadIndex;
            this.taskIndex = taskIndex;
        }

        public void run() {
            for (int i = taskIndex; i < taskIndex + 5; i++) {
                System.out.println("Thread " + Thread.currentThread().getId() + " running inner thread task " + i + " on " + outerThreadIndex + "-" + threadIndex);
                list.add(zero);
            }
            System.out.println("---------"+list.size());
        }
    }

    static class OuterThread implements Runnable {
        private int threadIndex;
        private int taskIndex;
        private CountDownLatch innerLatch;

        public OuterThread(int threadIndex, int taskIndex, CountDownLatch innerLatch) {
            this.threadIndex = threadIndex;
            this.taskIndex = taskIndex;
            this.innerLatch = innerLatch;
        }

        public void run() {
            for (int i = taskIndex; i < taskIndex + 2; i++) {
                CountDownLatch subInnerLatch = new CountDownLatch(INNER_THREAD_BATCH_COUNT);
                for (int j = 0; j < INNER_THREAD_BATCH_COUNT; j++) {
                    new Thread(new InnerThread(j, threadIndex, i)).start();
                }
                try {
                    subInnerLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            innerLatch.countDown();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread[] outerThreads = new Thread[OUTER_THREAD_COUNT];
        int currentTaskIndex = 0;

        for (int i = 0; i < OUTER_THREAD_COUNT; i++) {
            outerThreads[i] = null;
        }

        for (int i = 0; i < OUTER_THREAD_BATCH_COUNT; i++) {
            int startIndex = i * OUTER_TASK_COUNT/OUTER_THREAD_BATCH_COUNT;
            int endIndex = startIndex + OUTER_TASK_COUNT/OUTER_THREAD_BATCH_COUNT;

            for (int j = startIndex; j < endIndex; j++) {
                outerThreads[j] = new Thread(new OuterThread(j, currentTaskIndex, OUTER_LATCH));
            }

            for (int j = startIndex; j < endIndex; j++) {
                outerThreads[j].start();
            }

            System.out.println("currentTaskIndex"+currentTaskIndex);
            OUTER_LATCH.await();
            OUTER_LATCH.countDown();
            currentTaskIndex += 2;
            System.out.println("currentTaskIndex"+currentTaskIndex);
        }

//        OUTER_LATCH.await();
//        OUTER_LATCH.countDown();
//
//        currentTaskIndex = 12;

//        for (int i = 0; i < OUTER_THREAD_BATCH_COUNT; i++) {
//            int startIndex = i * OUTER_TASK_COUNT / OUTER_THREAD_BATCH_COUNT + OUTER_TASK_COUNT / 2;
//            int endIndex = startIndex + OUTER_TASK_COUNT / OUTER_THREAD_BATCH_COUNT;
//
//            for (int j = startIndex; j < endIndex; j++) {
//                outerThreads[j] = new Thread(new OuterThread(j, currentTaskIndex, OUTER_LATCH));
//            }
//
//            for (int j = startIndex; j < endIndex; j++) {
//                outerThreads[j].start();
//            }
//
//            OUTER_LATCH.await();
//            OUTER_LATCH.countDown();
//            currentTaskIndex += 2;
//        }
    }
}
//package org.example;
//
//import org.thymeleaf.expression.Lists;
//
//import java.util.ArrayList;
//import java.util.List;
//import java.util.concurrent.CountDownLatch;
//
//public class NestedThreadExample {
//    private static final int OUTER_THREAD_COUNT = 12;
//    private static final int INNER_THREAD_COUNT = 10;
//    private static final int OUTER_TASK_COUNT = 24;
//    private static final int OUTER_THREAD_BATCH_COUNT = 2; // 每批外部线程数
//    private static final int INNER_THREAD_BATCH_COUNT = 2; // 每批内部线程数
//    private static final CountDownLatch OUTER_LATCH = new CountDownLatch(OUTER_THREAD_BATCH_COUNT);
//
//    private static List<Integer> list = new ArrayList<>();
//
//    private static  int zero = 1;
//
//    static class InnerThread implements Runnable {
//        private int threadIndex;
//        private int outerThreadIndex;
//        private int taskIndex;
//
//        public InnerThread(int threadIndex, int outerThreadIndex, int taskIndex)  {
//            this.threadIndex = threadIndex;
//            this.outerThreadIndex = outerThreadIndex;
//            this.taskIndex = taskIndex;
//        }
//
//        public void run() {
//            for (int i = taskIndex; i < taskIndex + 5; i++) {
//                System.out.println("Thread " + Thread.currentThread().getId() + " running inner thread task " + i + " on " + outerThreadIndex + "-" + threadIndex);
//                list.add(zero);
//            }
//            System.out.println("---------"+list.size());
//        }
//    }
//
//    static class OuterThread implements Runnable {
//        private int threadIndex;
//        private int taskIndex;
//        private CountDownLatch innerLatch;
//
//        public OuterThread(int threadIndex, int taskIndex, CountDownLatch innerLatch) {
//            this.threadIndex = threadIndex;
//            this.taskIndex = taskIndex;
//            this.innerLatch = innerLatch;
//        }
//
//        public void run() {
//            for (int i = taskIndex; i < taskIndex + 2; i++) {
//                CountDownLatch subInnerLatch = new CountDownLatch(INNER_THREAD_BATCH_COUNT);
//                for (int j = 0; j < INNER_THREAD_BATCH_COUNT; j++) {
//                    new Thread(new InnerThread(j, threadIndex, i)).start();
//                }
//                try {
//                    subInnerLatch.await();
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//            innerLatch.countDown();
//        }
//    }
//
//    public static void main(String[] args) throws InterruptedException {
//        Thread[] outerThreads = new Thread[OUTER_THREAD_COUNT];
//        int currentTaskIndex = 0;
//
//        for (int i = 0; i < OUTER_THREAD_COUNT; i++) {
//            outerThreads[i] = null;
//        }
//
//        for (int i = 0; i < OUTER_THREAD_BATCH_COUNT; i++) {
//            int startIndex = i * OUTER_THREAD_COUNT / OUTER_THREAD_BATCH_COUNT;
//            int endIndex = startIndex + OUTER_THREAD_COUNT / OUTER_THREAD_BATCH_COUNT;
//
//            for (int j = startIndex; j < endIndex; j++) {
//                outerThreads[j] = new Thread(new OuterThread(j, currentTaskIndex, OUTER_LATCH));
//            }
//
//            for (int j = startIndex; j < endIndex; j++) {
//                outerThreads[j].start();
//            }
//
//            OUTER_LATCH.await();
//            OUTER_LATCH.countDown();
//            currentTaskIndex += 2;
//            System.out.println("currentTaskIndex:"+currentTaskIndex);
//        }
//    }
//}